<script setup lang="ts">
// ----------------------- 常量定义 -----------------------
// 图片相关常量
const IMAGE_CONFIG = {
  BASE_URL: 'http://localhost:5173/api',
  MAX_SIZE: 5, // MB
  ALLOWED_TYPES: ['image/jpeg', 'image/png', 'image/gif'],
  UPLOAD_URL: 'api/material/upload'
} as const

// 状态常量
const MATERIAL_STATUS = {
  ACTIVE: 0,
  INACTIVE: 1
} as const

// 表格配置
const TABLE_CONFIG = {
  PAGE_SIZES: [10, 20, 50, 100],
  DEFAULT_PAGE_SIZE: 10,
  MIN_HEIGHT_OFFSET: 260
} as const

// 导入配置
const IMPORT_CONFIG = {
  MAX_SIZE: 10, // MB
  ALLOWED_TYPES: [
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    'application/vnd.ms-excel'
  ]
} as const

// ----------------------- 导入相关依赖 -----------------------
import {nextTick, onMounted, onUnmounted, reactive, ref, computed, watch} from "vue";
import {ElMessage, FormInstance} from "element-plus";
import SysDialog from "@/components/dialog/SysDialog.vue";
import useDialog from "@/hooks/useDialog";
import useInstance from "@/hooks/useInstance";
import {Material, MaterialListParam, MaterialExportRequest, ExportField, MaterialImportResult, MaterialImportError, MaterialPriceImportResult, MaterialPriceImportError} from "@/api/material/type";
import {addApi, deleteApi, updateApi, getListApi, exportApi,refreshMaterialApi, importApi, exportCustomApi, downloadTemplateApi, getExportFieldsApi, updateProcessApi, downloadPriceTemplateApi, importPriceApi} from "@/api/material";
// 物料分类精简类别，用于树形结构展示
import {getSimpleListApi, getListApi as getCategoryListApi} from "@/api/materialCategory/index.ts";
// 物料分类新增相关导入
import {addApi as addCategoryApi} from "@/api/materialCategory/index.ts";
import {MaterialCategory, MaterialCategoryListParam} from "@/api/materialCategory/type.ts";
// 单位列表，用于物料单位下拉框
import {getUnitSimpleListApi} from "@/api/unit/index.ts";
// 工艺列表
import {getSimpleListApi as getProcessSimpleListApi} from "@/api/process/index.ts";
//工艺价格相关导入
import {addSonApi} from "@/api/process/index.ts";
import {ProcessSon} from "@/api/process/type.ts";
// 图标组件
import {Search, Refresh, Plus, Edit, Delete, Folder, Setting, InfoFilled, ZoomIn, Picture, Document, Grid, Upload, Download, DocumentCopy} from '@element-plus/icons-vue'
import TreeSelect from "@/components/TreeSelect/index.vue";
import {Unit} from "@/api/unit/type.ts";

// ----------------------- Composables 抽取 -----------------------
// 错误处理composable
const useErrorHandler = () => {
  const handleError = (error: any, defaultMessage: string = '操作失败，请稍后重试') => {
    console.error('操作失败:', error)
    
    let errorMessage = defaultMessage
    if (error?.response?.data?.message) {
      errorMessage = error.response.data.message
    } else if (error?.message) {
      errorMessage = error.message
    }
    
    const errorHandlers = {
      '系统繁忙': () => ElMessage({
        message: '系统繁忙，多人同时操作可能导致此问题，请稍后重试',
        type: 'warning',
        duration: 5000,
        showClose: true
      }),
      '物料编码生成失败': () => ElMessage({
        message: '物料编码生成失败，请稍后重试或联系系统管理员',
        type: 'error',
        duration: 5000,
        showClose: true
      }),
      '联系系统管理员': () => ElMessage({
        message: '系统异常，请联系系统管理员处理',
        type: 'error',
        duration: 8000,
        showClose: true
      }),
      '操作被中断': () => ElMessage({
        message: '操作被中断，请重新尝试',
        type: 'warning',
        duration: 3000,
        showClose: true
      })
    }
    
    const handler = Object.entries(errorHandlers).find(([key]) => errorMessage.includes(key))?.[1]
    if (handler) {
      handler()
    } else {
      ElMessage({
        message: errorMessage,
        type: 'error',
        duration: 5000,
        showClose: true
      })
    }
  }
  
  return { handleError }
}

// 图片处理composable
const useImageHandler = () => {
  const validateImage = (file: any): boolean => {
    const isValidType = IMAGE_CONFIG.ALLOWED_TYPES.some(type => 
      file.type === type || file.type.startsWith('image/')
    )
    const isValidSize = file.size / 1024 / 1024 < IMAGE_CONFIG.MAX_SIZE

    if (!isValidType) {
      ElMessage.error('只能上传图片文件（jpg、png、gif格式）')
      return false
    }
    if (!isValidSize) {
      ElMessage.error(`图片大小不能超过${IMAGE_CONFIG.MAX_SIZE}MB`)
      return false
    }
    return true
  }
  
  const getImageUrl = (imageUrl: string): string => {
    if (!imageUrl) return ''
    return imageUrl.startsWith('http') ? imageUrl : `${IMAGE_CONFIG.BASE_URL}${imageUrl}`
  }
  
  return { validateImage, getImageUrl }
}

// 表单验证composable
const useFormValidation = () => {
  const rules = {
    materialName: [{required: true, message: '请输入物料名称', trigger: 'blur'}],
    categoryId: [{required: true, message: '请选择物料分类', trigger: 'change'}],
    unitId: [{required: true, message: '请选择计量单位', trigger: 'change'}]
  }
  
  const validateForm = async (formRef: FormInstance | undefined): Promise<boolean> => {
    if (!formRef) return false
    try {
      await formRef.validate()
      return true
    } catch (error) {
      ElMessage.warning('请填写必填字段')
      return false
    }
  }
  
  return { rules, validateForm }
}

// ----------------------- 组件状态定义 -----------------------
const {dialog, onShow, onClose} = useDialog()
const {global} = useInstance()
const { handleError } = useErrorHandler()
const { validateImage, getImageUrl } = useImageHandler()
const { rules, validateForm } = useFormValidation()

// 表格高度自适应
const tableHeight = ref(0)

// ----------------------- 响应式数据 -----------------------
const tableData = ref([])
const loading = ref(false)
const paginationData = reactive({
  total: 0,
  currentPage: 1,
  pageSize: TABLE_CONFIG.DEFAULT_PAGE_SIZE
})

// 多选相关
const multipleSelection = ref<Material[]>([])
const selectAll = ref(false)
const selectIndeterminate = ref(false)

// ----------------------- 查询表单相关 -----------------------
const searchForm = reactive<MaterialListParam>({
  materialCode: undefined,
  materialName: undefined,
  categoryId: undefined,
  categoryName: undefined,  // 物料分类名称 - 新增
  brand: undefined,
  manufacturer: undefined,
  materialModel: undefined,
  materialType: undefined,
  isActive: undefined,
  page: 1,
  limit: TABLE_CONFIG.DEFAULT_PAGE_SIZE
})

// 计算属性：状态选项
const statusOptions = computed(() => [
  { label: '启用', value: MATERIAL_STATUS.ACTIVE },
  { label: '禁用', value: MATERIAL_STATUS.INACTIVE }
])

// 查询方法
const search = () => {
  paginationData.currentPage = 1
  getTableData()
}

// 重置查询 - 优化逻辑
const reset = () => {
  // 批量重置搜索条件，保留当前分类选择
  const currentCategoryId = searchForm.categoryId
  Object.assign(searchForm, {
    materialCode: undefined,
    materialName: undefined,
    categoryId: currentCategoryId,
    categoryName: undefined,  // 重置分类名称
    brand: undefined,
    manufacturer: undefined,
    materialModel: undefined,
    materialType: undefined,
    isActive: undefined
  })    
  search()
}

// ----------------------- 表格数据处理 -----------------------
const getTableData = async () => {
  loading.value = true
  try {
    // 同步分页参数
    Object.assign(searchForm, {
      page: paginationData.currentPage,
      limit: paginationData.pageSize
    })
    
    const res = await getListApi(searchForm)
    if (res?.data) {
      tableData.value = res.data.list
      paginationData.total = res.data.total
      // 清空选择
      multipleSelection.value = []
      updateSelectAllState()
    }
  } catch (error) {
    handleError(error, '获取表格数据失败')
  } finally {
    loading.value = false
  }
}

// ----------------------- 多选相关方法 -----------------------
// 处理表格选择变化
const handleSelectionChange = (selection: Material[]) => {
  multipleSelection.value = selection
  updateSelectAllState()
}

// 更新全选状态
const updateSelectAllState = () => {
  const total = tableData.value.length
  const selected = multipleSelection.value.length
  
  selectAll.value = selected > 0 && selected === total
  selectIndeterminate.value = selected > 0 && selected < total
}

// 处理全选/取消全选
const handleSelectAll = (checked: boolean) => {
  if (checked) {
    // 全选当前页面的所有数据
    multipleSelection.value = [...tableData.value]
  } else {
    // 取消全选
    multipleSelection.value = []
  }
  updateSelectAllState()
}

// 勾选导出功能
const exportSelected = async () => {
  if (multipleSelection.value.length === 0) {
    ElMessage.warning('请至少选择一条记录进行导出')
    return
  }

  // 限制导出数量，避免性能问题
  if (multipleSelection.value.length > 1000) {
    ElMessage.warning('一次最多只能导出1000条记录，请减少选择数量')
    return
  }

  try {
    // 确认导出操作
    const confirm = await global.$myConfirm(
      `确定要导出选中的 ${multipleSelection.value.length} 条物料记录吗？`, 
      '批量导出确认'
    )
    if (!confirm) return
  } catch {
    return // 用户取消
  }

  const loadingMsg = ElMessage({
    message: `正在导出${multipleSelection.value.length}条记录...`,
    type: 'info',
    duration: 0,
    showClose: false
  })

  try {
    // 构造导出请求，只导出选中的数据
    const exportRequest: MaterialExportRequest = {
      fields: ['materialCode', 'materialName', 'categoryName', 'unitName', 'specification', 'specificationTwo', 'price', 'purchasePrice', 'brand', 'manufacturer', 'materialModel', 'materialType'],
      selectedIds: multipleSelection.value.map(item => item.id).filter(id => id !== undefined)
    }
    
    const response = await exportCustomApi(exportRequest)
    // HTTP拦截器对blob类型返回完整的response对象，需要提取data
    const blob = response.data instanceof Blob ? response.data : new Blob([response.data], {
      type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    })
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = `物料档案_选中导出_${new Date().getTime()}.xlsx`
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)
    
    ElMessage.success(`成功导出${multipleSelection.value.length}条记录`)
  } catch (error) {
    console.error('导出失败:', error)
    handleError(error, '勾选导出失败')
  } finally {
    loadingMsg.close()
  }
}

// 勾选复制功能
const copySelected = async () => {
  if (multipleSelection.value.length === 0) {
    ElMessage.warning('请至少选择一条记录进行复制')
    return
  }

  // 确认复制操作
  try {
    const confirm = await global.$myConfirm(
      `确定要复制选中的 ${multipleSelection.value.length} 条物料记录吗？复制后的物料编码将自动生成，物料名称将添加"(复制)"标识。`, 
      '批量复制确认'
    )
    if (!confirm) return
  } catch {
    return // 用户取消
  }

  const loadingMsg = ElMessage({
    message: `正在复制${multipleSelection.value.length}条记录...`,
    type: 'info',
    duration: 0,
    showClose: false
  })

  try {
    let successCount = 0
    let failCount = 0
    const errors: string[] = []

    // 限制批量操作数量，避免性能问题
    if (multipleSelection.value.length > 50) {
      ElMessage.warning('一次最多只能复制50条记录，请减少选择数量')
      return
    }

    for (const item of multipleSelection.value) {
      try {
        // 创建复制的物料数据，移除ID和编码，其他属性保持一致
        const copyData: Material = {
          ...item,
          id: undefined,
          materialCode: undefined, // 后端会自动生成新的物料编码
          materialName: `${item.materialName}(复制)`, // 添加复制标识
          createTime: undefined,
          updateTime: undefined,
          fileList: []
        }

        await addApi(copyData)
        successCount++
      } catch (error) {
        failCount++
        errors.push(`${item.materialName}: ${(error as any)?.response?.data?.message || '复制失败'}`)
      }
    }

    // 显示结果
    if (successCount > 0) {
      ElMessage.success(`成功复制${successCount}条记录`)
      await getTableData() // 刷新数据
    }
    
    if (failCount > 0) {
      ElMessage.warning(`${failCount}条记录复制失败`)
      console.error('复制失败的记录:', errors)
      
      // 如果有错误，显示详细信息
      if (errors.length > 0 && errors.length <= 5) {
        setTimeout(() => {
          ElMessage({
            message: `失败详情：\n${errors.join('\n')}`,
            type: 'error',
            duration: 8000,
            showClose: true,
            dangerouslyUseHTMLString: false
          })
        }, 1000)
      }
    }

  } catch (error) {
    handleError(error, '批量复制失败')
  } finally {
    loadingMsg.close()
  }
}

// ----------------------- 物料分类新增相关 -----------------------
const categoryDialog = reactive({
  visible: false,
  title: '新增物料分类'
})

const categoryFormRef = ref<FormInstance>()

// 初始化物料分类表单数据
const createInitialCategoryForm = (): MaterialCategory => ({
  id: undefined,
  categoryCode: undefined,
  categoryName: undefined,
  description: undefined,
  parentId: undefined,
  areaJudgment: undefined,
  weightJudgment: undefined,
  weightTotalJudgment: undefined,
  areaTotalJudgment: undefined
})

const categoryForm = reactive<MaterialCategory>(createInitialCategoryForm())

// 物料分类表单验证规则
const categoryRules = {
  categoryName: [{required: true, message: '请输入分类名称', trigger: 'blur'}]
}

// 打开新增物料分类弹窗
const openAddCategory = () => {
  categoryDialog.title = '新增物料分类'
  Object.assign(categoryForm, createInitialCategoryForm())
  categoryDialog.visible = true
  nextTick(() => {
    categoryFormRef.value?.clearValidate()
  })
}

// 关闭物料分类弹窗
const closeCategoryDialog = () => {
  categoryDialog.visible = false
  Object.assign(categoryForm, createInitialCategoryForm())
}

// 提交新增物料分类
const submitCategory = async () => {
  if (!await validateForm(categoryFormRef.value)) return

  const loadingMsg = ElMessage({
    message: '正在创建分类中...',
    type: 'info',
    duration: 0,
    showClose: false
  })

  try {
    const response = await addCategoryApi(categoryForm)
    ElMessage.success('新增分类成功')
    
    // 重新加载分类数据
    await getParentCategories()
    await getTreeData()
    
    // 自动选中新创建的分类
    if (response?.data?.id) {
      addForm.categoryId = response.data.id
    }
    
    closeCategoryDialog()
  } catch (error) {
    handleError(error, '新增分类失败')
  } finally {
    loadingMsg.close()
  }
}

// ----------------------- 新增/编辑表单相关 -----------------------
const addFormRef = ref<FormInstance>()

// 初始化表单数据 - 使用函数返回新对象，避免引用问题
const createInitialForm = (): Material => ({
  id: undefined,
  materialCode: undefined,
  materialName: undefined,
  categoryId: undefined,
  categoryName: undefined,
  unitId: undefined,
  specification: undefined,
  specificationTwo: undefined,
  number: undefined,
  brand: undefined,
  manufacturer: undefined,
  price: undefined,
  purchasePrice: undefined,
  materialModel: undefined,
  materialType: undefined,
  unitWeight: undefined,
  unitArea: undefined,
  totalArea: undefined,
  totalWeight: undefined,
  thickness: undefined,
  length: undefined,
  breadth: undefined,
  weldingLength: undefined,
  imageUrl: undefined,
  process: undefined,
  mileagePrice: undefined,
  unitPriceCoefficient: undefined,
  materialRequisitionCoefficient: undefined,
  selectPrice: undefined, // 新增辅助项
  isActive: MATERIAL_STATUS.ACTIVE,
  createTime: undefined,
  updateTime: undefined,
  fileList: []
})

const addForm = reactive<Material>(createInitialForm())

// 表单重置方法 - 优化清理逻辑
const resetForm = () => {
  Object.assign(addForm, createInitialForm())
  nextTick(() => {
    addFormRef.value?.clearValidate()
  })
}

// 打开新增弹框
const openAdd = async () => {
  dialog.title = '新增物料'
  dialog.width = 900
  dialog.height = 400
  resetForm()
  
  // 确保分类选项数据已加载
  if (categorySearchOptions.value.length === 0) {
    await loadAllCategories()
  }
  
  onShow()
}

// 打开编辑弹框 - 优化数据赋值逻辑
const openEdit = async (row: Material) => {
  dialog.title = '编辑物料'
  dialog.width = 900
  dialog.height = 400
  
  resetForm()
  
  // 确保分类选项数据已加载，避免显示ID而不是分类名称
  await loadAllCategories()
  
  // 如果当前物料有分类ID但在选项中找不到对应的分类，则重新加载分类数据
  if (row.categoryId && !categorySearchOptions.value.find(option => option.value === row.categoryId)) {
    await loadAllCategories()
  }
  
  nextTick(() => {
    // 深拷贝数据避免直接修改原数据
    const formData = { ...row }
    
    // 处理图片文件列表
    if (row.imageUrl) {
      formData.fileList = [{
        name: row.imageUrl.split('/').pop() || '物料图片',
        url: getImageUrl(row.imageUrl)
      }]
    }
    
    Object.assign(addForm, formData)
  })
  onShow()
}

// 关闭弹框
const closeDialog = () => {
  resetForm()
  onClose()
}

// 提交表单 - 优化加载状态和错误处理
const submit = async () => {
  if (!await validateForm(addFormRef.value)) return

  const loadingMsg = ElMessage({
    message: addForm.id ? '正在保存中...' : '正在创建中...',
    type: 'info',
    duration: 0,
    showClose: false
  })

  try {
    // 准备提交数据，移除不需要的字段
    const submitData = { ...addForm }
    delete submitData.fileList

    if (addForm.id) {
      await updateApi(submitData)
      ElMessage.success('编辑成功')
    } else {
      await addApi(submitData)
      ElMessage.success('新增成功')
    }
    
    await getTableData()
    closeDialog()
  } catch (error) {
    handleError(error)
  } finally {
    loadingMsg.close()
  }
}

// ----------------------- 删除相关 -----------------------
const deleteOne = async (id: number) => {
  try {
    const confirm = await global.$myConfirm('确定要删除该物料吗？')
    if (!confirm) return

    await deleteApi(id)
    ElMessage.success('删除成功')
    
    // 智能分页处理：如果当前页只有一条数据且不是第一页，则跳转到上一页
    if (tableData.value.length === 1 && paginationData.currentPage > 1) {
      paginationData.currentPage--
    }
    
    await getTableData()
  } catch (error) {
    handleError(error, '删除失败')
  }
}


// ----------------------- 树形数据处理 -----------------------
// 上级分类选择器的数据
const parentOptions = ref<any[]>([])
// 搜索状态
const categorySearchOptions = ref<any[]>([])
const categorySearchLoading = ref(false)
let categorySearchTimer: NodeJS.Timeout | null = null

/**
 * 获取分类列表数据
 * 用于新增/编辑表单中的物料的分类选择
 */
const getParentCategories = async () => {
  try {
    const res = await getSimpleListApi()
    if (res?.data) {
      // 直接使用处理后的树形数据（用于新增分类弹窗的上级分类选择）
      parentOptions.value = handleParentTree(res.data)
      // 同时初始化搜索选项（用于物料分类选择）
      categorySearchOptions.value = handleSelectOptions(res.data)
    }
  } catch (error) {
    console.error('获取分类列表失败:', error)
    ElMessage.error('获取分类列表失败')
  }
}

/**
 * 搜索物料分类
 * @param query 搜索关键词
 */
const searchCategories = async (query: string) => {
  if (!query || query.trim() === '') {
    // 如果搜索为空，加载所有分类
    await loadAllCategories()
    return
  }

  categorySearchLoading.value = true
  
  try {
    const searchParam: MaterialCategoryListParam = {
      categoryName: query.trim(),
      categoryCode: undefined,
      parentId: undefined,
      page: 1,
      limit: 100 // 获取更多结果用于搜索
    }
    
    const res = await getCategoryListApi(searchParam)
    if (res?.data?.list) {
      // 处理搜索结果为select选项格式
      categorySearchOptions.value = handleSelectOptions(res.data.list)
    } else {
      categorySearchOptions.value = []
    }
  } catch (error) {
    console.error('搜索分类失败:', error)
    categorySearchOptions.value = []
  } finally {
    categorySearchLoading.value = false
  }
}

/**
 * 处理分类数据为select选项格式
 * @param data 原始分类数据
 * @returns select选项数组
 */
const handleSelectOptions = (data: any[]): any[] => {
  // 创建一个映射表以便查找父分类
  const categoryMap = new Map()
  data.forEach(item => {
    categoryMap.set(item.id, item)
  })
  
  return data.map(item => ({
    id: item.id,
    value: item.id,
    label: item.categoryName,
    parentName: item.parentId && item.parentId !== "0" ? getParentCategoryName(item.parentId, categoryMap) : null
  }))
}

/**
 * 获取父分类名称
 * @param parentId 父分类ID
 * @param categoryMap 分类映射表
 * @returns 父分类名称
 */
const getParentCategoryName = (parentId: string | number, categoryMap: Map<any, any>): string => {
  const parent = categoryMap.get(parentId)
  return parent ? parent.categoryName : ''
}

/**
 * 处理分类选择器焦点事件
 */
const handleCategorySelectFocus = () => {
  // 每次焦点时都确保显示所有分类（用于remote模式）
  if (categorySearchOptions.value.length === 0) {
    loadAllCategories()
  }
}

/**
 * 处理下拉框显示/隐藏事件
 */
const handleCategoryVisibleChange = (visible: boolean) => {
  if (visible && categorySearchOptions.value.length === 0) {
    // 当下拉框显示且没有选项时，加载所有分类
    loadAllCategories()
  }
}

/**
 * 加载所有分类选项
 */
const loadAllCategories = async () => {
  try {
    categorySearchLoading.value = true
    const res = await getSimpleListApi()
    if (res?.data) {
      categorySearchOptions.value = handleSelectOptions(res.data)
    }
  } catch (error) {
    console.error('加载分类选项失败:', error)
  } finally {
    categorySearchLoading.value = false
  }
}

/**
 * 防抖搜索分类
 * @param query 搜索关键词
 */
const debouncedSearchCategories = (query: string) => {
  if (categorySearchTimer) {
    clearTimeout(categorySearchTimer)
  }
  
  categorySearchTimer = setTimeout(() => {
    searchCategories(query)
  }, 300) // 300ms防抖
}

/**
 * 处理分类树形数据
 * @param data 原始数据
 * @returns 处理后的树形数据
 */
const handleParentTree = (data: any[]) => {
  const map = new Map()
  const result: any[] = []

  // 初始化映射表
  data.forEach(item => {
    map.set(item.id, {
      id: item.id,
      value: item.id,
      label: item.categoryName,
      children: []
    })
  })

  // 构建树形结构
  data.forEach(item => {
    const node = map.get(item.id)
    if (item.parentId === "0") {
      // 顶级分类直接加入结果数组
      result.push(node)
    } else {
      const parent = map.get(item.parentId)
      if (parent) {
        parent.children.push(node)
      }
    }
  })
  return result
}


// ----------------------- 左侧筛选树形数据处理 -----------------------
// 当前选中的分类ID，用于树形筛选
const currentCategoryId = ref<number>()

// 定义树节点类型
interface TreeNode {
  id: string;
  categoryName: string;
  parentId: string;
  children: TreeNode[];
}

// 左侧筛选树形数据
const treeData = ref<TreeNode[]>([])
/**
 * 获取侧筛选树形数据
 */
const getTreeData = async () => {
  try {
    const res = await getSimpleListApi()
    if (res?.data) {
      treeData.value = handleTree(res.data)
    }
  } catch (error) {
    console.error('获取树形数据失败:', error)
    ElMessage.error('获取分类数据失败')
  }
}

/**
 * 处理左侧筛选树形结构
 * @param data 原始数据
 * @returns 处理后的树形数据，包含虚拟顶级节点
 */
const handleTree = (data: TreeNode[]): TreeNode[] => {
  const map = new Map<string, TreeNode>();
  const result: TreeNode[] = [];

  // 创建虚拟的顶级节点
  const rootNode: TreeNode = {
    id: '-1',
    categoryName: '全部分类',
    parentId: '',
    children: [],
  };

  // 初始化映射表
  data.forEach((item) => {
    map.set(item.id, {...item, children: []});
  });

  // 构建树形结构
  data.forEach((item) => {
    const node = map.get(item.id)!;
    if (item.parentId === "0") {
      rootNode.children.push(node);
    } else {
      const parent = map.get(item.parentId);
      if (parent) {
        parent.children.push(node);
      }
    }
  });

  result.push(rootNode);
  return result;
};


/**
 * 树节点点击事件处理
 */
const handleTreeNodeClick = async (data: any) => {
  // 处理虚拟顶级节点点击
  if (data.id === '-1') {
    currentCategoryId.value = undefined;
    searchForm.categoryId = undefined;
  } else {
    currentCategoryId.value = data.id;
    searchForm.categoryId = data.id;
  }
  // 重置分页和搜索条件
  searchForm.page = 1;
  searchForm.limit = 10;
  searchForm.materialCode = undefined
  searchForm.materialName = undefined
  searchForm.categoryName = undefined  // 重置分类名称
  searchForm.brand = undefined
  searchForm.manufacturer = undefined
  searchForm.materialType = undefined
  searchForm.isActive = undefined
  await getTableData();
}


// ---------------------- 物料单位，用于物料单位下拉框 ----------------------
const unitOptions = ref<Unit[]>([])

// 获取单位数据
const getUnitData = async () => {
  try {
    const res = await getUnitSimpleListApi()
    if (res?.data) {
      unitOptions.value = res.data
    }
  } catch (error) {
    console.error('获取物料单位数据失败:', error)
    ElMessage.error('获取物料单位数据失败')
  }
}

// ---------------------- 工艺相关数据，用于工艺下拉框 ----------------------
const processOptions = ref<any[]>([])

// 获取工艺数据
const getProcessData = async () => {
  try {
    const res = await getProcessSimpleListApi()
    if (res?.data) {
      processOptions.value = res.data
    }
  } catch (error) {
    console.error('获取工艺数据失败:', error)
    ElMessage.error('获取工艺数据失败')
  }
}

// ---------------------- 工艺价格新增相关 ----------------------
const processDialog = reactive({
  visible: false,
  title: '新增工艺价格'
})

const processFormRef = ref<FormInstance>()

// 初始化工艺价格表单数据
const createInitialProcessForm = (): ProcessSon => ({
  id: undefined,
  pid: undefined,
  productName: undefined,
  cost: undefined,
  heightMin: undefined,
  heightMax: undefined,
  thicknessMin: undefined,
  thicknessMax: undefined,
  material: undefined,
  number: undefined,
  height: undefined,
  thickness: undefined,
  isDelete: 0
})

const processForm = reactive<ProcessSon>(createInitialProcessForm())

// 工艺价格表单验证规则
const processRules = {
  pid: [{required: true, message: '请选择工艺', trigger: 'change'}],
  productName: [{required: true, message: '请输入产品名称', trigger: 'blur'}],
  cost: [{required: true, message: '请输入单价', trigger: 'blur'}]
}

// 打开新增工艺价格弹窗
const openAddProcess = () => {
  processDialog.title = '新增工艺价格'
  Object.assign(processForm, createInitialProcessForm())
  processDialog.visible = true
  nextTick(() => {
    processFormRef.value?.clearValidate()
  })
}

// 关闭工艺价格弹窗
const closeProcessDialog = () => {
  processDialog.visible = false
  Object.assign(processForm, createInitialProcessForm())
}

// 提交新增工艺价格
const submitProcess = async () => {
  if (!await validateForm(processFormRef.value)) return

  const loadingMsg = ElMessage({
    message: '正在创建工艺价格中...',
    type: 'info',
    duration: 0,
    showClose: false
  })

  try {
    await addSonApi(processForm)
    ElMessage.success('新增工艺价格成功')
    closeProcessDialog()
  } catch (error) {
    handleError(error, '新增工艺价格失败')
  } finally {
    loadingMsg.close()
  }
}

// ----------------------- 文件上传 -----------------------
const handleUploadSuccess = (response: any, file: any) => {
  // 假设后端返回的格式是 { imageUrl: 'xxx' }
  console.log(response);
  addForm.imageUrl = response.data
  addForm.fileList = [file] // 更新文件列表
}

// ----------------------- 图片预览相关 -----------------------
const previewVisible = ref(false)
const previewImageUrl = ref('')
const previewImageTitle = ref('')

// 图片预览处理
const handlePictureCardPreview = (file: any) => {
  // 处理上传组件的图片预览
  if (file) {
    previewImageUrl.value = file.url || ('http://localhost:5173/api' + addForm.imageUrl)
    previewImageTitle.value = file.name || '物料图片'
    previewVisible.value = true
  }
};

// 表格中图片预览
const handleTableImagePreview = (imageUrl: string, title: string) => {
  if (imageUrl) {
    previewImageUrl.value = 'http://localhost:5173/api' + imageUrl
    previewImageTitle.value = title || '物料图片'
    previewVisible.value = true
  }
}

// 关闭预览
const closePreview = () => {
  previewVisible.value = false
}

// 打开原图
const openOriginalImage = () => {
  if (previewImageUrl.value) {
    window.open(previewImageUrl.value)
  }
}

// 图片移除处理
const handleRemove = () => {
  addForm.imageUrl = undefined // 使用undefined而不是null
  addForm.fileList = []
  // 确保上传组件状态重置
  nextTick(() => {
    addFormRef.value?.clearValidate('imageUrl')
  })
}

// ----------------------- 导入相关 -----------------------
const importDialog = reactive({
  visible: false,
  loading: false,
  fileList: [] as any[]
})

// 导入错误详情对话框
const importErrorDialog = reactive({
  visible: false,
  result: null as MaterialImportResult | null
})

// 材料单价导入对话框
const priceImportDialog = reactive({
  visible: false,
  loading: false,
  fileList: [] as any[]
})

// 材料单价导入错误详情对话框
const priceImportErrorDialog = reactive({
  visible: false,
  result: null as MaterialPriceImportResult | null
})

// 显示导入对话框
const showImportDialog = () => {
  importDialog.visible = true
  importDialog.fileList = []
}

// 关闭导入对话框
const closeImportDialog = () => {
  importDialog.visible = false
  importDialog.fileList = []
  importDialog.loading = false
}

// 导入文件前校验
const beforeImportUpload = (file: any) => {
  const isExcel = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || 
                  file.type === 'application/vnd.ms-excel'
  const isLt10M = file.size / 1024 / 1024 < 10

  if (!isExcel) {
    ElMessage.error('只能上传Excel文件')
    return false
  }
  if (!isLt10M) {
    ElMessage.error('文件大小不能超过10MB')
    return false
  }
  return false // 阻止自动上传
}

// 文件选择改变
const handleImportFileChange = (file: any, fileList: any[]) => {
  importDialog.fileList = fileList
}

// 移除文件
const handleImportFileRemove = () => {
  importDialog.fileList = []
}

// 确认导入
const confirmImport = async () => {
  if (importDialog.fileList.length === 0) {
    ElMessage.warning('请选择要导入的文件')
    return
  }

  importDialog.loading = true
  try {
    const formData = new FormData()
    formData.append('file', importDialog.fileList[0].raw)
    
    const response = await importApi(formData)
    
    // HTTP拦截器返回: { code: 200, message: "成功", data: MaterialImportResult }
    // 实际的导入结果在data字段中
    const result = (response as any).data as MaterialImportResult
    
    // 处理导入结果
    if (result.success) {
      ElMessage.success(result.message)
      closeImportDialog()
      await getTableData() // 刷新表格数据
    } else {
      // 有错误的情况
      showImportErrorDialog(result)
    }
  } catch (error) {
    console.error('导入失败:', error)
    ElMessage.error('导入失败，请检查文件格式')
  } finally {
    importDialog.loading = false
  }
}

// 显示导入错误详情对话框
const showImportErrorDialog = (result: MaterialImportResult) => {
  console.log('显示导入结果对话框:', result) // 调试日志
  importErrorDialog.result = result
  importErrorDialog.visible = true
  // 先关闭导入对话框
  closeImportDialog()
  
  // 显示概要消息
  if (result.successCount > 0) {
    ElMessage.success(`成功导入 ${result.successCount} 条记录`)
  }
  if (result.failCount > 0) {
    ElMessage.warning(`${result.failCount} 条记录导入失败，请查看详情`)
  }
}

// 关闭导入错误详情对话框
const closeImportErrorDialog = () => {
  importErrorDialog.visible = false
  importErrorDialog.result = null
  // 刷新表格数据
  getTableData()
}

// 获取错误类型标签样式
const getErrorTypeTagType = (errorType: string) => {
  const typeMap: Record<string, string> = {
    'VALIDATION_ERROR': 'danger',
    'CATEGORY_NOT_FOUND': 'warning',
    'UNIT_NOT_FOUND': 'warning',
    'DATA_FORMAT_ERROR': 'danger',
    'PROCESSING_ERROR': 'danger',
    'SAVE_ERROR': 'danger',
    'SYSTEM_ERROR': 'danger',
    'PARSING_ERROR': 'danger'
  }
  return typeMap[errorType] || 'info'
}

// 获取错误类型标签文本
const getErrorTypeLabel = (errorType: string) => {
  const labelMap: Record<string, string> = {
    'VALIDATION_ERROR': '数据验证',
    'CATEGORY_NOT_FOUND': '分类不存在',
    'UNIT_NOT_FOUND': '单位不存在',
    'DATA_FORMAT_ERROR': '格式错误',
    'PROCESSING_ERROR': '处理异常',
    'SAVE_ERROR': '保存失败',
    'SYSTEM_ERROR': '系统错误',
    'PARSING_ERROR': '解析错误'
  }
  return labelMap[errorType] || errorType
}

// ----------------------- 导出相关 -----------------------
//刷新物料
const refreshMaterial = async () => {
    const response = await refreshMaterialApi()
    ElMessage.success('刷新成功')
} 
// 普通导出
const exportMaterial = async () => {
  try {
    const response = await exportApi(searchForm)
    // HTTP拦截器对blob类型返回完整的response对象，需要提取data
    const blob = response.data instanceof Blob ? response.data : new Blob([response.data], {
      type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    })
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = `物料档案_${new Date().getTime()}.xlsx`
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)
    ElMessage.success('导出成功')
  } catch (error) {
    console.error('导出失败:', error)
    ElMessage.error('导出失败')
  }
}

// 自定义导出对话框
const exportDialog = reactive({
  visible: false,
  loading: false,
  availableFields: [] as ExportField[],
  form: {
    selectedFields: [] as string[],
    exportType: 'filtered' as 'all' | 'filtered'
  }
})

// 显示自定义导出对话框
const showCustomExportDialog = async () => {
  try {
    const response = await getExportFieldsApi()
    if (response.data) {
      exportDialog.availableFields = response.data
      exportDialog.form.selectedFields = ['materialCode', 'materialName', 'categoryName', 'unitName'] // 默认选择基础字段
    }
    exportDialog.visible = true
  } catch (error) {
    console.error('获取导出字段失败:', error)
    ElMessage.error('获取导出字段失败')
  }
}

// 关闭自定义导出对话框
const closeExportDialog = () => {
  exportDialog.visible = false
  exportDialog.form.selectedFields = []
  exportDialog.form.exportType = 'filtered'
  exportDialog.loading = false
}

// 全选字段
const selectAllFields = () => {
  exportDialog.form.selectedFields = exportDialog.availableFields.map(field => field.fieldName)
}

// 清空字段
const clearAllFields = () => {
  exportDialog.form.selectedFields = []
}

// 确认自定义导出
const confirmCustomExport = async () => {
  if (exportDialog.form.selectedFields.length === 0) {
    ElMessage.warning('请至少选择一个导出字段')
    return
  }

  exportDialog.loading = true
  try {
    const exportRequest: MaterialExportRequest = {
      fields: exportDialog.form.selectedFields,
      searchParam: exportDialog.form.exportType === 'filtered' ? searchForm : undefined
    }
    
    const response = await exportCustomApi(exportRequest)
    // HTTP拦截器对blob类型返回完整的response对象，需要提取data
    const blob = response.data instanceof Blob ? response.data : new Blob([response.data], {
      type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    })
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = `物料档案_自定义导出_${new Date().getTime()}.xlsx`
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)
    
    ElMessage.success('导出成功')
    closeExportDialog()
  } catch (error) {
    console.error('自定义导出失败:', error)
    ElMessage.error('自定义导出失败')
  } finally {
    exportDialog.loading = false
  }
}

// 下载模板
const downloadTemplate = async () => {
  try {
    const response = await downloadTemplateApi()
    // HTTP拦截器对blob类型返回完整的response对象，需要提取data
    const blob = response.data instanceof Blob ? response.data : new Blob([response.data], {
      type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    })
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = '物料导入模板.xlsx'
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)
    ElMessage.success('模板下载成功')
  } catch (error) {
    console.error('下载模板失败:', error)
    ElMessage.error('下载模板失败')
  }
}

// 这部分代码已经在下方定义，无需重复

const beforeUpload = (file: any) => {
  const isImage = file.type.startsWith('image/')
  const isLt5M = file.size / 1024 / 1024 < 5

  if (!isImage) {
    ElMessage.error('只能上传图片文件')
    return false
  }
  if (!isLt5M) {
    ElMessage.error('图片大小不能超过5MB')
    return false
  }

  return true
}

// ----------------------- 生命周期钩子 -----------------------
onMounted(async () => {
  // 左侧筛选树形数据
  getTreeData()
  // 表格数据
  getTableData()
  nextTick(() => {
    tableHeight.value = window.innerHeight - 260
  })
  // 分类选择器的数据
  await getParentCategories();
  // 物料单位，下拉框数据
  getUnitData();
  // 工艺下拉框数据
  getProcessData();
  
  // 初始化物料分类选择器的选项（确保第一次点击时有数据显示）
  await loadAllCategories()
})

// 监听窗口大小变化
const handleResize = () => {
  nextTick(() => {
    tableHeight.value = window.innerHeight - 260
  })
}

onMounted(() => {
  window.addEventListener('resize', handleResize)
})

onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
  // 清理搜索定时器
  if (categorySearchTimer) {
    clearTimeout(categorySearchTimer)
  }
})

// ----------------------- 材料单价更新相关 -----------------------
// 显示材料单价导入对话框
const showPriceImportDialog = () => {
  priceImportDialog.visible = true
  priceImportDialog.fileList = []
}

// 关闭材料单价导入对话框
const closePriceImportDialog = () => {
  priceImportDialog.visible = false
  priceImportDialog.fileList = []
  priceImportDialog.loading = false
}

// 材料单价导入文件前校验
const beforePriceImportUpload = (file: any) => {
  const isExcel = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || 
                file.type === 'application/vnd.ms-excel'
  const isLt10M = file.size / 1024 / 1024 < 10

  if (!isExcel) {
    ElMessage.error('只能上传Excel文件')
    return false
  }
  if (!isLt10M) {
    ElMessage.error('文件大小不能超过10MB')
    return false
  }
  return false // 阻止自动上传
}

// 材料单价文件选择改变
const handlePriceImportFileChange = (file: any, fileList: any[]) => {
  priceImportDialog.fileList = fileList
}

// 移除材料单价文件
const handlePriceImportFileRemove = () => {
  priceImportDialog.fileList = []
}

// 确认导入材料单价
const confirmPriceImport = async () => {
  if (priceImportDialog.fileList.length === 0) {
    ElMessage.warning('请选择要导入的文件')
    return
  }

  priceImportDialog.loading = true
  try {
    const formData = new FormData()
    formData.append('file', priceImportDialog.fileList[0].raw)
    
    const response = await importPriceApi(formData)
    
    // 解析API返回的数据结构，真正的结果在data字段中
    const result = response.data
    console.log('导入API返回:', response) // 调试日志
    console.log('解析后的结果:', result) // 调试日志
    
    // 处理导入结果 - 使用解析后的result
    showPriceImportErrorDialog(result)
    
    // 根据结果显示相应的消息
    if (result.success && result.successCount > 0) {
      ElMessage.success(result.message)
    } else if (result.successCount > 0 && result.failCount > 0) {
      ElMessage.warning(`部分成功：成功${result.successCount}条，失败${result.failCount}条`)
    } else if (result.failCount > 0) {
      ElMessage.error(`导入失败：${result.failCount}条记录有错误`)
    } else {
      ElMessage.warning('没有找到可以处理的数据')
    }
    closePriceImportDialog()
    await getTableData() // 刷新表格数据
  } catch (error) {
    console.error('导入失败:', error)
    ElMessage.error('导入失败，请检查文件格式')
  } finally {
    priceImportDialog.loading = false
  }
}

// 显示材料单价导入错误详情对话框
const showPriceImportErrorDialog = (result: MaterialPriceImportResult) => {
  console.log('显示材料单价导入结果对话框:', result) // 调试日志
  priceImportErrorDialog.result = result
  priceImportErrorDialog.visible = true
  // 先关闭导入对话框
  closePriceImportDialog()
  
  // 显示概要消息
  if (result.successCount > 0) {
    ElMessage.success(`成功更新 ${result.successCount} 条记录`)
  }
  if (result.failCount > 0) {
    ElMessage.warning(`${result.failCount} 条记录更新失败，请查看详情`)
  }
}

// 关闭材料单价导入错误详情对话框
const closePriceImportErrorDialog = () => {
  priceImportErrorDialog.visible = false
  priceImportErrorDialog.result = null
  // 刷新表格数据
  getTableData()
}

// 下载材料单价更新模板
const downloadPriceTemplate = async () => {
  try {
    const response = await downloadPriceTemplateApi()
    // HTTP拦截器对blob类型返回完整的response对象，需要提取data
    const blob = response.data instanceof Blob ? response.data : new Blob([response.data], {
      type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    })
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = '材料单价更新模板.xlsx'
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)
    ElMessage.success('模板下载成功')
  } catch (error) {
    console.error('下载模板失败:', error)
    ElMessage.error('下载模板失败')
  }
}

const updateLoading = ref(false)
const handleUpdateProcess = async () => {
  updateLoading.value = true
  try {
    await updateProcessApi()
    ElMessage.success('工艺修改成功')
  } catch (e) {
    ElMessage.error('工艺修改失败')
  } finally {
    updateLoading.value = false
  }
}
</script>

<template>
  <el-main class="material-main">
    <div class="main-container">
      <el-row :gutter="20">
        <!-- 左侧树形菜单 -->
        <el-col :span="4">
          <el-card class="tree-card" shadow="hover">
            <div class="tree-header">
              <el-icon :size="18"><Folder /></el-icon>
              <span>物料分类</span>
            </div>
            <TreeSelect
              :data="treeData"
              :props="{
                children: 'children',
                label: 'categoryName'
              }"
              placeholder="请输入分类名称"
              @node-click="handleTreeNodeClick"
              class="category-tree"
            />
          </el-card>
        </el-col>
        
        <!-- 右侧内容区 -->
        <el-col :span="20">
          <!-- 查询表单区域 -->
          <el-card class="search-card" shadow="hover">
            <el-form :inline="true" :model="searchForm" class="search-form">
              <el-form-item label="物料编码">
                <el-input 
                  v-model="searchForm.materialCode" 
                  placeholder="请输入物料编码" 
                  clearable 
                  prefix-icon="Document"
                />
              </el-form-item>
              <el-form-item label="物料名称">
                <el-input 
                  v-model="searchForm.materialName" 
                  placeholder="请输入物料名称" 
                  clearable 
                  prefix-icon="Goods"
                />
              </el-form-item>
              <el-form-item label="物料分类">
                <el-input 
                  v-model="searchForm.categoryName" 
                  placeholder="请输入分类名称" 
                  clearable 
                  prefix-icon="Folder"
                />
              </el-form-item>
              <el-form-item label="物料型号">
                <el-input 
                  v-model="searchForm.materialModel" 
                  placeholder="请输入物料型号" 
                  clearable 
                  prefix-icon="Grid" 
                />
              </el-form-item>
  
              <el-form-item label="材质">
                <el-input 
                  v-model="searchForm.materialType" 
                  placeholder="请输入材质" 
                  clearable 
                  prefix-icon="Setting" 
                />
              </el-form-item>
              <el-form-item label="状态">
                <el-select 
                  v-model="searchForm.isActive" 
                  placeholder="请选择状态" 
                  clearable
                  style="width: 120px"
                >
                  <el-option label="启用" :value="0" />
                  <el-option label="禁用" :value="1" />
                </el-select>
              </el-form-item>
              <el-form-item class="search-buttons">
                <el-button type="primary" @click="search" class="search-btn" :icon="Search">
                  查询
                </el-button>
                <el-button @click="reset" class="reset-btn" :icon="Refresh">
                  重置
                </el-button>
                <el-button type="success" @click="openAdd" class="add-btn" :icon="Plus">
                  新增
                </el-button>
                <el-button type="warning" @click="showImportDialog" class="import-btn" :icon="Upload">
                  导入
                </el-button>
                <el-button type="success" @click="showPriceImportDialog" class="price-import-btn" :icon="Upload">
                  更新材料单价
                </el-button>
                <el-button type="info" @click="exportMaterial" class="export-btn" :icon="Download">
                  导出
                </el-button>
                <el-button type="primary" @click="showCustomExportDialog" class="custom-export-btn" :icon="DocumentCopy">
                  自定义导出
                </el-button>
                <el-button type="default" @click="downloadTemplate" class="template-btn" :icon="Download">
                  下载模板
                </el-button>
                <el-button type="danger"  @click="refreshMaterial">
                  刷新物料数据
                </el-button>
              </el-form-item>
            </el-form>
            
            <!-- 批量操作区域 -->
            <transition name="batch-slide">
              <div v-if="multipleSelection.length > 0" class="batch-operations">
                <div class="batch-info">
                  <el-checkbox 
                    v-model="selectAll" 
                    :indeterminate="selectIndeterminate"
                    @change="handleSelectAll"
                    class="select-all-checkbox"
                  >
                    全选当前页
                  </el-checkbox>
                  <span class="selected-count">已选择 {{ multipleSelection.length }} 项</span>
                  <el-tag v-if="multipleSelection.length >= 50" type="warning" size="small">
                    <el-icon><InfoFilled /></el-icon>
                    复制操作限制50条
                  </el-tag>
                  <el-tag v-if="multipleSelection.length >= 1000" type="danger" size="small">
                    <el-icon><InfoFilled /></el-icon>
                    导出操作限制1000条
                  </el-tag>
                </div>
                <div class="batch-buttons">
                  <el-button 
                    type="success" 
                    size="small" 
                    @click="exportSelected" 
                    :icon="Download"
                    :disabled="multipleSelection.length > 1000"
                  >
                    导出选中 ({{ multipleSelection.length }})
                  </el-button>
                  <el-button 
                    type="warning" 
                    size="small" 
                    @click="copySelected" 
                    :icon="DocumentCopy"
                    :disabled="multipleSelection.length > 50"
                  >
                    复制选中 ({{ multipleSelection.length }})
                  </el-button>
                  <el-button size="small" @click="multipleSelection = []; updateSelectAllState()" plain>
                    取消选择
                  </el-button>
                </div>
              </div>
            </transition>
          </el-card>

          <!-- 表格区域 -->
          <el-card class="table-card" shadow="hover">
            <el-table
              v-loading="loading"
              :data="tableData"
              border
              :height="tableHeight"
              class="data-table"
              highlight-current-row
              @selection-change="handleSelectionChange"
            >
              <!-- 复选框列 -->
              <el-table-column type="selection" width="55" align="center" fixed="left"/>
              <el-table-column type="index" label="序号" width="70" align="center"/>
              <el-table-column prop="materialCode" label="物料编码" min-width="120" align="center" show-overflow-tooltip />
              <el-table-column prop="materialName" label="物料名称" min-width="150" align="center" show-overflow-tooltip />
              <el-table-column prop="categoryName" label="物料分类" min-width="120" align="center" show-overflow-tooltip />
              <el-table-column prop="materialModel" label="物料型号" min-width="120" align="center" show-overflow-tooltip />

              <!-- 新增：材料查询辅助项 -->
              <el-table-column prop="selectPrice" label="材料查询辅助项" min-width="120" align="center" show-overflow-tooltip />

              <el-table-column prop="updateTime" label="更细时间" min-width="120" align="center" show-overflow-tooltip />

              <el-table-column label="图片" width="120" align="center">
                <template #default="scope">
                  <el-image
                    v-if="scope.row.imageUrl"
                    style="width: 80px; height: 80px; border-radius: 6px; object-fit: cover; cursor: pointer;"
                    :src="'http://localhost:5173/api' + scope.row.imageUrl"
                    fit="cover"
                    @click="handleTableImagePreview(scope.row.imageUrl, scope.row.materialName)"
                  >
                    <template #error>
                      <div class="image-error">
                        <el-icon><Picture /></el-icon>
                        <span>加载失败</span>
                      </div>
                    </template>
                  </el-image>
                  <div v-else class="no-image">
                    <el-icon><Picture /></el-icon>
                    <span>暂无图片</span>
                  </div>
                </template>
              </el-table-column>
              <el-table-column prop="unitName" label="计量单位" min-width="90" align="center" show-overflow-tooltip />
              <el-table-column prop="specification" label="规格" min-width="120" align="center" show-overflow-tooltip />
              <el-table-column prop="specificationTwo" label="规格2" min-width="120" align="center" show-overflow-tooltip />
              <el-table-column prop="price" label="采购价格" min-width="100" align="center" show-overflow-tooltip>
                <template #default="scope">
                  <span v-if="scope.row.price">{{ scope.row.price }} 元</span>
                  <span v-else class="no-data">-</span>
                </template>
              </el-table-column>
              <el-table-column prop="purchasePrice" label="采购单价" min-width="100" align="center" show-overflow-tooltip>
                <template #default="scope">
                  <span v-if="scope.row.purchasePrice">{{ scope.row.purchasePrice }} 元</span>
                  <span v-else class="no-data">-</span>
                </template>
              </el-table-column>
              <el-table-column prop="brand" label="品牌" min-width="100" align="center" show-overflow-tooltip />
              <el-table-column prop="manufacturer" label="生产厂家" min-width="150" align="center" show-overflow-tooltip />
              <el-table-column prop="materialType" label="材质" min-width="100" align="center" show-overflow-tooltip />  
              <el-table-column prop="unitWeight" label="米重(kg/m)" min-width="100" align="center" show-overflow-tooltip>
                <template #default="scope">
                  <span v-if="scope.row.unitWeight">{{ scope.row.unitWeight }}</span>
                  <span v-else class="no-data">-</span>
                </template>
              </el-table-column>
              <el-table-column prop="unitArea" label="面积(m²/m)" min-width="100" align="center" show-overflow-tooltip>
                <template #default="scope">
                  <span v-if="scope.row.unitArea">{{ scope.row.unitArea }}</span>
                  <span v-else class="no-data">-</span>
                </template>
              </el-table-column>
              <el-table-column prop="totalArea" label="总面积(m²/件)" min-width="110" align="center" show-overflow-tooltip>
                <template #default="scope">
                  <span v-if="scope.row.totalArea">{{ scope.row.totalArea }}</span>
                  <span v-else class="no-data">-</span>
                </template>
              </el-table-column>
              <el-table-column prop="totalWeight" label="总重(kg/件)" min-width="100" align="center" show-overflow-tooltip>
                <template #default="scope">
                  <span v-if="scope.row.totalWeight">{{ scope.row.totalWeight }}</span>
                  <span v-else class="no-data">-</span>
                </template>
              </el-table-column>
              <el-table-column prop="thickness" label="厚度(mm)" min-width="100" align="center" show-overflow-tooltip>
                <template #default="scope">
                  <span v-if="scope.row.thickness">{{ scope.row.thickness }}</span>
                  <span v-else class="no-data">-</span>
                </template>
              </el-table-column>
              <el-table-column prop="length" label="长度" min-width="100" align="center" show-overflow-tooltip>
                <template #default="scope">
                  <span v-if="scope.row.length">{{ scope.row.length }}</span>
                  <span v-else class="no-data">-</span>
                </template>
              </el-table-column>
              <el-table-column prop="breadth" label="宽度" min-width="100" align="center" show-overflow-tooltip>
                <template #default="scope">
                  <span v-if="scope.row.breadth">{{ scope.row.breadth }}</span>
                  <span v-else class="no-data">-</span>
                </template>
              </el-table-column>
              <!-- <el-table-column prop="weldingLength" label="焊接长度(m)" min-width="110" align="center" show-overflow-tooltip>
                <template #default="scope">
                  <span v-if="scope.row.weldingLength">{{ scope.row.weldingLength }}</span>
                  <span v-else class="no-data">-</span>
                </template>
              </el-table-column> -->
              <el-table-column prop="process" label="工艺" min-width="120" align="center" show-overflow-tooltip />
              <el-table-column prop="mileagePrice" label="人工公里数单价" min-width="120" align="center" show-overflow-tooltip>
                <template #default="scope">
                  <span v-if="scope.row.mileagePrice">{{ scope.row.mileagePrice }}</span>
                  <span v-else class="no-data">-</span>
                </template>
              </el-table-column>
              <el-table-column prop="isActive" label="状态" min-width="80" align="center">
                <template #default="scope">
                  <el-tag :type="scope.row.isActive === 0 ? 'success' : 'danger'">
                    {{ scope.row.isActive === 0 ? '启用' : '禁用' }}
                  </el-tag>
                </template>
              </el-table-column>
              <el-table-column label="操作" width="160" fixed="right" align="center">
                <template #default="scope">
                  <div class="action-buttons">
                    <el-button type="primary" size="small" :icon="Edit" @click="openEdit(scope.row)" class="edit-btn">
                      编辑
                    </el-button>
                    <el-button type="danger" size="small" :icon="Delete" @click="deleteOne(scope.row.id)" class="delete-btn">
                      删除
                    </el-button>
                  </div>
                </template>
              </el-table-column>
            </el-table>

            <!-- 分页 -->
            <el-pagination
              v-model:current-page="paginationData.currentPage"
              v-model:page-size="paginationData.pageSize"
              :page-sizes="[10, 20, 50]"
              :total="paginationData.total"
              layout="total, sizes, prev, pager, next, jumper"
              class="pagination"
              @size-change="getTableData"
              @current-change="getTableData"
            />
          </el-card>
        </el-col>
      </el-row>
    </div>

    <!-- 新增/编辑弹框 -->
    <sys-dialog
        :title="dialog.title"
        :width="dialog.width"
        :visible="dialog.visible"
        :height="dialog.height"
        @onClose="closeDialog"
        @onConfirm="submit"
        custom-class="material-dialog"
        destroy-on-close
    >
      <template #content>
        <el-scrollbar height="100%" class="form-scrollbar">
          <el-form
              ref="addFormRef"
              :model="addForm"
              :rules="rules"
              label-width="90px"
              class="material-form"
          >
            <el-card class="form-card" shadow="never">
              <template #header>
                <div class="form-header">
                  <el-icon><Document /></el-icon>
                  <span>基本信息</span>
                </div>
              </template>
              <el-row :gutter="20">
                <el-col :span="12">
                  <el-form-item label="物料名称" prop="materialName">
                    <el-input v-model="addForm.materialName" placeholder="请输入物料名称" clearable />
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <!-- 编辑时显示物料编码 -->
                  <el-form-item v-if="addForm.id" label="物料编码">
                    <el-input v-model="addForm.materialCode" readonly>
                      <template #prefix>
                        <el-icon><Grid /></el-icon>
                      </template>
                    </el-input>
                  </el-form-item>
                  <!-- 新增时显示提示信息 -->
                
                </el-col>
              </el-row>

              <el-row :gutter="20">
                <el-col :span="12">
                  <el-form-item label="物料分类" prop="categoryId">
                    <div class="category-select-wrapper">
                      <el-select
                          class="category-select"
                          v-model="addForm.categoryId"
                          placeholder="请选择物料分类（支持搜索）"
                          filterable
                          clearable
                          remote
                          reserve-keyword
                          :remote-method="debouncedSearchCategories"
                          :loading="categorySearchLoading"
                          @focus="handleCategorySelectFocus"
                          @visible-change="handleCategoryVisibleChange"
                      >
                        <el-option
                          v-for="item in categorySearchOptions"
                          :key="item.id"
                          :label="item.label"
                          :value="item.value"
                        >
                          <span class="category-option">
                            <span class="category-name">{{ item.label }}</span>
                            <span v-if="item.parentName" class="category-parent">{{ item.parentName }}</span>
                          </span>
                        </el-option>
                      </el-select>
                      <el-button 
                        type="primary" 
                        :icon="Plus" 
                        @click="openAddCategory"
                        class="add-category-btn"
                        title="新增分类"
                      >
                        新增
                      </el-button>
                    </div>
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="计量单位" prop="unitId">
                    <el-select v-model="addForm.unitId" filterable clearable placeholder="请选择计量单位" class="full-width">
                      <el-option v-for="unit in unitOptions" :key="unit.id" :label="unit.unitName" :value="unit.id">
                        <span style="float: left">{{ unit.unitName }}</span>
                        <span style="float: right; color: var(--el-text-color-secondary); font-size: 13px;">{{ unit.unitSymbol }}</span>
                      </el-option>
                    </el-select>
                  </el-form-item>
                </el-col>
              </el-row>

              <el-row :gutter="20">
                <el-col :span="12">
                  <el-form-item label="规格">
                    <el-input v-model="addForm.specification" placeholder="请输入规格" clearable />
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="规格2">
                    <el-input v-model="addForm.specificationTwo" placeholder="请输入规格2" clearable />
                  </el-form-item>
                </el-col>
        
              </el-row>

              <el-row :gutter="20">
              <el-col :span="12">
                <el-form-item label="物料型号">
                    <el-input v-model="addForm.materialModel" placeholder="请输入物料型号" clearable />
                  </el-form-item>
                </el-col>

                <el-col :span="12">
                  <el-form-item label="厚度">
                    <el-input-number
                      v-model="addForm.thickness"
                      :precision="2"
                      :step="0.1"
                      :min="0"
                      placeholder="请输入厚度(mm)"
                      class="full-width"
                    />
                  </el-form-item>
                </el-col>
              </el-row>

              <el-row :gutter="20">
                <el-col :span="12">
                  <el-form-item label="工艺">
                    <div class="process-input-wrapper">
                      <el-input v-model="addForm.process" placeholder="请输入工艺" clearable class="process-input" />
                      <el-button 
                        type="primary" 
                        :icon="Plus" 
                        @click="openAddProcess"
                        class="add-process-btn"
                        title="新增工艺价格"
                      >
                        新增价格
                      </el-button>
                    </div>
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="品牌">
                    <el-input v-model="addForm.brand" placeholder="请输入品牌" clearable />
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row :gutter="20">
                <el-col :span="12">
                  <el-form-item label="生产厂家">
                    <el-input v-model="addForm.manufacturer" placeholder="请输入生产厂家" clearable />
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="采购价格">
                    <el-input-number
                        v-model="addForm.price"
                        :precision="2"
                        :step="0.1"
                        :min="0"
                        placeholder="请输入采购价格"
                        class="full-width"
                    />
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row :gutter="20">
                <el-col :span="12">
                  <el-form-item label="采购单价">
                    <el-input-number
                        v-model="addForm.purchasePrice"
                        :precision="2"
                        :step="0.1"
                        :min="0"
                        placeholder="请输入采购单价"
                        class="full-width"
                    />
                  </el-form-item>
                </el-col>
              </el-row>

              <!-- 新增：材料查询辅助项 -->
              <el-row :gutter="20">
                <el-col :span="12">
                  <el-form-item label="材料查询辅助项">
                    <el-input v-model="addForm.selectPrice" placeholder="请输入材料查询辅助项" clearable />
                  </el-form-item>
                </el-col>
              </el-row>
            </el-card>

            <el-card class="form-card" shadow="never">
              <template #header>
                <div class="form-header">
                  <el-icon><Setting /></el-icon>
                  <span>物料规格参数</span>
                </div>
              </template>

              <el-row :gutter="20">
                <el-col :span="12">
                  <el-form-item label="材质">
                    <el-input v-model="addForm.materialType" placeholder="请输入材质" clearable />
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="米重">
                    <el-input-number
                      v-model="addForm.unitWeight"
                      :precision="2"
                      :step="0.1"
                      :min="0"
                      placeholder="请输入米重(kg/m)"
                      class="full-width"
                    />
                  </el-form-item>
                </el-col>
              </el-row>

              <el-row :gutter="20">
                <el-col :span="12">
                  <el-form-item label="米面积">
                    <el-input-number
                      v-model="addForm.unitArea"
                      :precision="2"
                      :step="0.1"
                      :min="0"
                      placeholder="请输入米面积(m²/m)"
                      class="full-width"
                    />
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="总面积">
                    <el-input-number
                      v-model="addForm.totalArea"
                      :precision="2"
                      :step="0.1"
                      :min="0"
                      placeholder="请输入总面积(m²/件)"
                      class="full-width"
                    />
                  </el-form-item>
                </el-col>
              </el-row>

              <el-row :gutter="20">
                <el-col :span="12">
                  <el-form-item label="总重">
                    <el-input-number
                      v-model="addForm.totalWeight"
                      :precision="2"
                      :step="0.1"
                      :min="0"
                      placeholder="请输入总重(kg/件)"
                      class="full-width"
                    />
                  </el-form-item>
                </el-col>

                
                <el-col :span="12">
                  <el-form-item label="焊接长度">
                    <el-input-number
                      v-model="addForm.weldingLength"
                      :precision="2"
                      :step="0.1"
                      :min="0"
                      placeholder="请输入焊接长度(m)"
                      class="full-width"
                    />
                  </el-form-item>
                </el-col>

              </el-row>

              <el-row :gutter="20">
                
                <el-col :span="8">
                  <el-form-item label="宽度">
                    <el-input-number
                      v-model="addForm.breadth"
                      :precision="2"
                      :step="0.1"
                      :min="0"
                      placeholder="请输入宽度"
                      class="full-width"
                    />
                  </el-form-item>
                </el-col>
                <el-col :span="8">
                  <el-form-item label="长度">
                    <el-input-number
                      v-model="addForm.length"
                      :precision="2"
                      :step="0.1"
                      :min="0"
                      placeholder="请输入长度"
                      class="full-width"
                    />
                  </el-form-item>
                </el-col>
              </el-row>

            </el-card>

            <el-card class="form-card" shadow="never">
              <template #header>
                <div class="form-header">
                  <el-icon><Grid /></el-icon>
                  <span>成本计算参数</span>
                </div>
              </template>

              <el-row :gutter="20">
                <el-col :span="12">
                  <el-form-item label="人工公里数单价">
                    <el-input v-model="addForm.mileagePrice" placeholder="请输入人工公里数单价" clearable />
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="单价索取系数">
                    <el-input v-model="addForm.unitPriceCoefficient" placeholder="请输入单价索取系数" clearable />
                  </el-form-item>
                </el-col>
              </el-row>

              <el-row :gutter="20">
                <el-col :span="12">
                  <el-form-item label="材料索取系数">
                    <el-input v-model="addForm.materialRequisitionCoefficient" placeholder="请输入材料索取系数" clearable />
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="启用状态">
                    <el-select v-model="addForm.isActive" placeholder="请选择启用状态" class="full-width">
                      <el-option label="启用" :value="0" />
                      <el-option label="禁用" :value="1" />
                    </el-select>
                  </el-form-item>
                </el-col>
              </el-row>
            </el-card>

            <el-card class="form-card" shadow="never">
              <template #header>
                <div class="form-header">
                  <el-icon><Picture /></el-icon>
                  <span>物料图片</span>
                </div>
              </template>

              <el-row :gutter="20">
                <el-col :span="24">
                  <el-form-item label="物料图片">
                    <el-upload
                      action="api/material/upload"
                      list-type="picture-card"
                      :file-list="addForm.fileList"
                      :on-preview="handlePictureCardPreview"
                      :on-remove="handleRemove"
                      :on-success="handleUploadSuccess"
                      :before-upload="beforeUpload"
                      :limit="1"
                      class="material-upload"
                    >
                      <template #default>
                        <el-icon><Plus /></el-icon>
                        <div class="upload-text">上传图片</div>
                      </template>
                      <template #file="{ file }">
                        <div class="upload-file">
                          <img class="upload-image" :src="file.url" alt="图片预览"/>
                          <div class="upload-actions">
                            <el-icon @click.stop="handlePictureCardPreview(file)"><ZoomIn /></el-icon>
                            <el-icon @click.stop="handleRemove()"><Delete /></el-icon>
                          </div>
                        </div>
                      </template>
                    </el-upload>
                    <div class="upload-tips">
                      <el-icon><InfoFilled /></el-icon>
                      <span>支持jpg/png格式，大小不超过5MB</span>
                    </div>
                  </el-form-item>
                </el-col>
              </el-row>
            </el-card>
          </el-form>
        </el-scrollbar>
      </template>
    </sys-dialog>
    
    <!-- 图片预览对话框 -->
    <el-dialog
      v-model="previewVisible"
      :title="previewImageTitle"
      width="700px"
      class="preview-dialog"
      @close="closePreview"
      destroy-on-close
      append-to-body
    >
      <div class="preview-container">
        <img :src="previewImageUrl" alt="预览图片" class="preview-image" />
      </div>
      <template #footer>
        <div class="preview-footer">
          <el-button @click="closePreview">关闭</el-button>
          <el-button type="primary" @click="openOriginalImage">查看原图</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 导入对话框 -->
    <el-dialog 
      v-model="importDialog.visible" 
      title="物料档案导入"
      width="500px"
      class="import-dialog"
      :destroy-on-close="true"
    >
      <el-form>
        <el-form-item label="选择Excel文件：">
          <el-upload
            ref="uploadRef"
            class="upload-demo"
            drag
            action="#"
            :auto-upload="false"
            :file-list="importDialog.fileList"
            accept=".xlsx,.xls"
            :limit="1"
            :before-upload="beforeImportUpload"
            :on-change="handleImportFileChange"
            :on-remove="handleImportFileRemove"
          >
            <el-icon class="el-icon--upload"><Upload /></el-icon>
            <div class="el-upload__text">
              将文件拖到此处，或<em>点击上传</em>
            </div>
            <template #tip>
              <div class="el-upload__tip">
                只能上传xlsx/xls文件，且不超过10MB
              </div>
            </template>
          </el-upload>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="closeImportDialog">取消</el-button>
          <el-button type="primary" @click="confirmImport" :loading="importDialog.loading">
            开始导入
          </el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 导入错误详情对话框 -->
    <el-dialog 
      v-model="importErrorDialog.visible" 
      :title="`导入结果详情`"
      width="800px"
      class="import-error-dialog"
      :destroy-on-close="true"
    >
      <div v-if="importErrorDialog.result">
        <!-- 导入结果摘要 -->
        <el-alert 
          :title="importErrorDialog.result.message"
          :type="importErrorDialog.result.success ? 'success' : 'warning'"
          show-icon
          :closable="false"
          class="result-summary"
        />
        
        <!-- 导入统计 -->
        <el-row :gutter="20" class="import-stats">
          <el-col :span="6">
            <el-statistic title="总记录数" :value="importErrorDialog.result.successCount + importErrorDialog.result.failCount" />
          </el-col>
          <el-col :span="6">
            <el-statistic title="成功导入" :value="importErrorDialog.result.successCount" />
          </el-col>
          <el-col :span="6">
            <el-statistic title="新增记录" :value="importErrorDialog.result.insertCount" />
          </el-col>
          <el-col :span="6">
            <el-statistic title="更新记录" :value="importErrorDialog.result.updateCount" />
          </el-col>
        </el-row>
        
        <!-- 错误详情 -->
        <div v-if="importErrorDialog.result.failCount > 0" class="error-details">
          <h4>失败记录详情（{{ importErrorDialog.result.failCount }} 条）</h4>
          <el-table 
            :data="importErrorDialog.result.failureDetails" 
            border
            stripe
            max-height="300"
            class="error-table"
          >
            <el-table-column prop="rowNumber" label="行号" width="80" align="center" />
            <el-table-column prop="materialCode" label="物料编码" width="120" />
            <el-table-column prop="materialName" label="物料名称" width="150" />
            <el-table-column prop="errorType" label="错误类型" width="120">
              <template #default="scope">
                <el-tag 
                  :type="getErrorTypeTagType(scope.row.errorType)"
                  size="small"
                >
                  {{ getErrorTypeLabel(scope.row.errorType) }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="errorMessage" label="错误原因" min-width="200" />
          </el-table>
        </div>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" @click="closeImportErrorDialog">确定</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 自定义导出对话框 -->
    <el-dialog 
      v-model="exportDialog.visible" 
      title="自定义字段导出"
      width="600px"
      class="export-dialog"
      :destroy-on-close="true"
    >
      <el-form :model="exportDialog.form" label-width="100px">
        <el-form-item label="选择字段：">
          <el-checkbox-group v-model="exportDialog.form.selectedFields" class="field-checkboxes">
            <el-checkbox
              v-for="field in exportDialog.availableFields"
              :key="field.fieldName"
              :label="field.fieldName"
              class="field-checkbox"
            >
              {{ field.displayName }}
            </el-checkbox>
          </el-checkbox-group>
        </el-form-item>
        <el-form-item label="导出范围：">
          <el-radio-group v-model="exportDialog.form.exportType">
            <el-radio label="all">导出全部数据</el-radio>
            <el-radio label="filtered">导出当前筛选结果</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="closeExportDialog">取消</el-button>
          <el-button @click="selectAllFields">全选</el-button>
          <el-button @click="clearAllFields">清空</el-button>
          <el-button type="primary" @click="confirmCustomExport" :loading="exportDialog.loading">
            导出
          </el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 新增物料分类对话框 -->
    <el-dialog
      v-model="categoryDialog.visible"
      :title="categoryDialog.title"
      width="500px"
      class="category-dialog"
      :destroy-on-close="true"
      append-to-body
    >
      <el-form
        ref="categoryFormRef"
        :model="categoryForm"
        :rules="categoryRules"
        label-width="100px"
        class="category-form"
      >
      <el-form-item label="分类编码" prop="categoryCode">
          <el-input 
            v-model="categoryForm.categoryCode" 
            placeholder="请输入分类编码" 
            clearable 
            maxlength="50"
            show-word-limit
          />
        </el-form-item>
        <el-form-item label="分类名称" prop="categoryName">
          <el-input 
            v-model="categoryForm.categoryName" 
            placeholder="请输入分类名称" 
            clearable 
            maxlength="50"
            show-word-limit
          />
        </el-form-item>
                 <el-form-item label="上级分类">
           <el-tree-select
             v-model="categoryForm.parentId"
             :data="parentOptions"
             :render-after-expand="false"
             show-checkbox
             check-strictly
             placeholder="请选择上级分类（可选）"
             filterable
             clearable
             class="full-width"
           />
          <div class="form-tips">
            <el-icon><InfoFilled /></el-icon>
            <span>不选择则创建为顶级分类</span>
          </div>
        </el-form-item>
        <el-form-item label="分类描述">
          <el-input 
            v-model="categoryForm.description" 
            type="textarea" 
            placeholder="请输入分类描述（可选）" 
            :rows="3"
            maxlength="200"
            show-word-limit
          />
        </el-form-item>
        <el-form-item label="单面积公式">
          <el-input 
            v-model="categoryForm.areaJudgment" 
            type="textarea"
            :rows="3"
            placeholder="请输入单面积判定公式（可选）" 
            clearable
          />
        </el-form-item>
        <el-form-item label="单重公式">
          <el-input 
            v-model="categoryForm.weightJudgment" 
            type="textarea"
            :rows="3"
            placeholder="请输入单重判定公式（可选）" 
            clearable
          />
        </el-form-item>
        <el-form-item label="总面积公式">
          <el-input 
            v-model="categoryForm.areaTotalJudgment" 
            type="textarea"
            :rows="3"
            placeholder="请输入总面积判定公式（可选）" 
            clearable
          />
        </el-form-item>
        <el-form-item label="总重公式">
          <el-input 
            v-model="categoryForm.weightTotalJudgment" 
            type="textarea"
            :rows="3"
            placeholder="请输入总重判定公式（可选）" 
            clearable
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="closeCategoryDialog">取消</el-button>
          <el-button type="primary" @click="submitCategory">
            确定
          </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 新增工艺价格对话框 -->
    <el-dialog
      v-model="processDialog.visible"
      :title="processDialog.title"
      width="900px"
      class="process-dialog"
      :destroy-on-close="true"
      append-to-body
    >
      <el-form
        ref="processFormRef"
        :model="processForm"
        :rules="processRules"
        label-width="100px"
        class="process-form"
      >
        <el-card class="form-card" shadow="never">
          <template #header>
            <div class="form-header">
              <el-icon><Document /></el-icon>
              <span>基本信息</span>
            </div>
          </template>
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="产品名称" prop="productName">
                <el-input v-model="processForm.productName" placeholder="请输入产品名称" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="工艺" prop="pid">
                <el-select v-model="processForm.pid" placeholder="请选择工艺" class="full-width">
                  <el-option
                    v-for="item in processOptions"
                    :key="item.id"
                    :label="item.processName"
                    :value="item.id">
                  </el-option>
                </el-select>          
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="20">
                <el-col :span="12">
                  <el-form-item label="材质" prop="material">
                    <el-input v-model="processForm.material" placeholder="请输入材质" />
                  </el-form-item>
                </el-col>
              </el-row>       
        </el-card>
        
        <el-card class="form-card" shadow="never">
          <template #header>
            <div class="form-header">
              <el-icon><Setting /></el-icon>
              <span>成本信息</span>
            </div>
          </template>
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="单价" prop="cost">
                <el-input-number v-model="processForm.cost" placeholder="请输入单价" :precision="2" :step="0.1" :min="0" class="full-width" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="数量">
                <el-input-number v-model="processForm.number" placeholder="请输入数量" :precision="0" :step="1" :min="0" class="full-width" />
              </el-form-item>
            </el-col>
          </el-row>
        </el-card>
       
        <el-card class="form-card" shadow="never">
          <template #header>
            <div class="form-header">
              <el-icon><Grid /></el-icon>
              <span>尺寸规格</span>
            </div>
          </template> 
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="最小高度">
                <el-input-number
                  v-model="processForm.heightMin"
                  :precision="2"
                  :step="0.1"
                  :min="0"
                  placeholder="请输入最小高度"
                  class="full-width"
                />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="最大高度(包含)">
                <el-input-number
                  v-model="processForm.heightMax"
                  :precision="2"
                  :step="0.1"
                  :min="0"
                  placeholder="请输入最大高度"
                  class="full-width"
                />
              </el-form-item>
            </el-col>
          </el-row>

          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="最小厚度">
                <el-input-number
                  v-model="processForm.thicknessMin"
                  :precision="2"
                  :step="0.1"
                  :min="0"
                  placeholder="请输入最小厚度"
                  class="full-width"
                />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="最大厚度(包含)">
                <el-input-number
                  v-model="processForm.thicknessMax"
                  :precision="2"
                  :step="0.1"
                  :min="0"
                  placeholder="请输入最大厚度"
                  class="full-width"
                />
              </el-form-item>
            </el-col>
          </el-row>

          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="材质">
                <el-input v-model="processForm.material" placeholder="请输入材质" clearable />
              </el-form-item>
            </el-col>
          </el-row>
        </el-card>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="closeProcessDialog">取消</el-button>
          <el-button type="primary" @click="submitProcess">
            确定
          </el-button>
        </div>
      </template>
    </el-dialog>
    
    <!-- 材料单价导入对话框 -->
    <el-dialog 
      v-model="priceImportDialog.visible" 
      title="材料单价更新"
      width="500px"
      class="import-dialog"
      :destroy-on-close="true"
    >
      <el-form>
        <el-form-item label="选择Excel文件：">
          <el-upload
            ref="priceUploadRef"
            class="upload-demo"
            drag
            action="#"
            :auto-upload="false"
            :file-list="priceImportDialog.fileList"
            accept=".xlsx,.xls"
            :limit="1"
            :before-upload="beforePriceImportUpload"
            :on-change="handlePriceImportFileChange"
            :on-remove="handlePriceImportFileRemove"
          >
            <el-icon class="el-icon--upload"><Upload /></el-icon>
            <div class="el-upload__text">
              将文件拖到此处，或<em>点击上传</em>
            </div>
            <template #tip>
              <div class="el-upload__tip">
                只能上传xlsx/xls文件，且不超过10MB
              </div>
            </template>
          </el-upload>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="closePriceImportDialog">取消</el-button>
          <el-button type="primary" @click="confirmPriceImport" :loading="priceImportDialog.loading">
            开始导入
          </el-button>
          <el-button type="info" @click="downloadPriceTemplate">
            下载模板
          </el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 材料单价导入错误详情对话框 -->
    <el-dialog 
      v-model="priceImportErrorDialog.visible" 
      :title="`材料单价更新结果详情`"
      width="800px"
      class="import-error-dialog"
      :destroy-on-close="true"
    >
      <div v-if="priceImportErrorDialog.result">
        <!-- 导入结果摘要 -->
        <el-alert 
          :title="priceImportErrorDialog.result.message"
          :type="priceImportErrorDialog.result.success ? 'success' : 'warning'"
          show-icon
          :closable="false"
          class="result-summary"
        />
        
        <!-- 导入统计 -->
        <el-row :gutter="20" class="import-stats">
          <el-col :span="8">
            <el-statistic title="总记录数" :value="priceImportErrorDialog.result.totalCount" />
          </el-col>
          <el-col :span="8">
            <el-statistic title="成功更新" :value="priceImportErrorDialog.result.successCount" />
          </el-col>
          <el-col :span="8">
            <el-statistic title="失败记录" :value="priceImportErrorDialog.result.failCount" />
          </el-col>
        </el-row>
        
        <!-- 错误详情 -->
        <div v-if="priceImportErrorDialog.result.failCount > 0 && priceImportErrorDialog.result.errorList?.length > 0" class="error-details">
          <h4>失败记录详情（{{ priceImportErrorDialog.result.failCount }} 条）</h4>
          <el-table 
            :data="priceImportErrorDialog.result.errorList" 
            border
            stripe
            max-height="300"
            class="error-table"
          >
            <el-table-column prop="rowIndex" label="行号" width="80" align="center" />
            <el-table-column prop="selectPrice" label="材料查询辅助项" width="150" />
            <el-table-column prop="errorType" label="错误类型" width="120">
              <template #default="scope">
                <el-tag 
                  :type="getErrorTypeTagType(scope.row.errorType)"
                  size="small"
                >
                  {{ getErrorTypeLabel(scope.row.errorType) }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="errorMessage" label="错误原因" min-width="200" />
          </el-table>
        </div>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" @click="closePriceImportErrorDialog">确定</el-button>
        </span>
      </template>
    </el-dialog>
  </el-main>
</template>

<style scoped lang="scss">
.material-main {
  padding: 0;
}

.main-container {
  padding: 20px;
  background-color: #f5f7fa;
  min-height: calc(100vh - 60px);
}

.tree-card {
  border-radius: 8px;
  height: calc(100vh - 100px);
  
  :deep(.el-card__body) {
    padding: 15px;
    height: 100%;
    display: flex;
    flex-direction: column;
  }
  
  .tree-header {
    padding: 12px 0;
    margin-bottom: 10px;
    display: flex;
    align-items: center;
    font-size: 16px;
    font-weight: 600;
    color: #67c23a;
    border-bottom: 1px solid #e1f3d8;
    
    .el-icon {
      margin-right: 8px;
      color: #67c23a;
    }
  }
  
  .category-tree {
    height: calc(100vh - 160px);
    overflow: auto;
    flex: 1;
    
    :deep(.el-tree-node__content) {
      height: 36px;
      
      &:hover {
        background-color: #f0f9eb;
      }
    }
    
    :deep(.el-tree-node.is-current > .el-tree-node__content) {
      background-color: #e1f3d8;
      color: #67c23a;
    }
  }
}

.search-card {
  margin-bottom: 20px;
  border-radius: 8px;
  transition: all 0.3s;
  
  :deep(.el-card__body) {
    padding: 15px 20px;
  }
}

.search-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  
  .el-form-item {
    margin-bottom: 0;
    margin-right: 16px;
  }
  
  .search-buttons {
    margin-left: auto;
    
    .el-button {
      margin-left: 8px;
      transition: all 0.3s;
      
      &:first-child {
        margin-left: 0;
      }
    }
    
    .search-btn {
      background: linear-gradient(135deg, #1989fa, #0056b3);
      border: none;
      
      &:hover {
        opacity: 0.9;
        transform: translateY(-2px);
        box-shadow: 0 4px 12px rgba(25, 137, 250, 0.3);
      }
    }
    
    .add-btn {
      background: linear-gradient(135deg, #67c23a, #409eff);
      border: none;
      
      &:hover {
        opacity: 0.9;
        transform: translateY(-2px);
        box-shadow: 0 4px 12px rgba(103, 194, 58, 0.3);
      }
    }
    
    .reset-btn:hover {
      transform: translateY(-2px);
      box-shadow: 0 4px 12px rgba(144, 147, 153, 0.2);
    }
  }
}

.table-card {
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
  height: calc(100vh - 180px);
  margin-bottom: 0;
  
  :deep(.el-card__body) {
    padding: 0;
    height: 100%;
    display: flex;
    flex-direction: column;
  }
}

.data-table {
  border-radius: 4px;
  flex: 1;
  
  :deep(.el-table__header-wrapper) {
    th {
      background-color: #f2f6fc;
      font-weight: 600;
    }
  }
  
  :deep(.el-table__row) {
    &:hover {
      td {
        background-color: #ecf5ff;
      }
    }
  }
  
  .no-image {
    height: 80px;
    width: 80px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background-color: #f7f7f7;
    color: #909399;
    font-size: 12px;
    border-radius: 6px;
    gap: 5px;
    
    .el-icon {
      font-size: 22px;
      color: #c0c4cc;
    }
  }
  
  .image-error {
    height: 80px;
    width: 80px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background-color: #f5f5f5;
    color: #909399;
    font-size: 12px;
    border-radius: 6px;
    gap: 5px;
    
    .el-icon {
      font-size: 22px;
      color: #c0c4cc;
    }
  }
  
  .no-data {
    color: #c0c4cc;
  }
  
  .action-buttons {
    display: flex;
    justify-content: center;
    
    .el-button {
      padding: 6px 10px;
      transition: all 0.3s;
      
      &:hover {
        transform: translateY(-2px);
      }
    }
    
    .edit-btn {
      margin-right: 10px;
    }
  }
}

.pagination {
  padding: 15px 20px;
  justify-content: flex-end;
  background: #fff;
  border-radius: 0 0 8px 8px;
}

// 弹窗样式
:deep(.material-dialog) {
  border-radius: 8px;
  overflow: hidden;
  
  .el-dialog__header {
    padding: 15px 20px;
    margin: 0;
    background: linear-gradient(90deg, #f0f9eb, #e1f3d8);
    border-bottom: 1px solid #e1f3d8;
    
    .el-dialog__title {
      font-size: 16px;
      font-weight: 600;
      color: #67c23a;
    }
    
    .el-dialog__headerbtn {
      top: 15px;
    }
  }
  
  .el-dialog__body {
    padding: 0;
  }
  
  .el-dialog__footer {
    padding: 10px 20px;
    border-top: 1px solid #ebeef5;
    background-color: #f5f7fa;
    
    .el-button {
      padding: 8px 20px;
      border-radius: 4px;
      transition: all 0.3s;
      
      &:hover {
        transform: translateY(-2px);
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
      }
    }
  }
}

.form-scrollbar {
  max-height: calc(80vh - 120px);
  overflow-y: auto;
}

.material-form {
  padding: 20px;
  
  .form-card {
    margin-bottom: 15px;
    border-radius: 8px;
    transition: all 0.3s;
    overflow: hidden;
    border: 1px solid #ebeef5;
    
    &:last-child {
      margin-bottom: 0;
    }
    
    :deep(.el-card__header) {
      padding: 10px 15px;
      background: linear-gradient(90deg, #f0f9eb, #e1f3d8);
      border-bottom: 1px solid #e1f3d8;
    }
    
    .form-header {
      font-size: 16px;
      font-weight: 600;
      color: #67c23a;
      display: flex;
      align-items: center;
      gap: 8px;
      
      .el-icon {
        color: #67c23a;
      }
    }
  }
  
  .material-upload {
    :deep(.el-upload--picture-card) {
      width: 140px;
      height: 140px;
      border-radius: 8px;
      background-color: #fafafa;
      border: 1px dashed #d9d9d9;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 10px;
      
      .el-icon {
        font-size: 24px;
        color: #67c23a;
      }
      
      .upload-text {
        font-size: 14px;
        color: #67c23a;
      }
      
      &:hover {
        border-color: #67c23a;
        background-color: #f0f9eb;
      }
    }
    
    :deep(.el-upload-list--picture-card) {
      .el-upload-list__item {
        width: 140px;
        height: 140px;
        border-radius: 8px;
        overflow: hidden;
      }
    }
    
    .upload-file {
      position: relative;
      width: 100%;
      height: 100%;
      
      .upload-image {
        width: 100%;
        height: 100%;
        object-fit: cover;
      }
      
      .upload-actions {
        position: absolute;
        bottom: 0;
        left: 0;
        right: 0;
        background-color: rgba(0, 0, 0, 0.5);
        display: flex;
        justify-content: center;
        gap: 15px;
        padding: 8px 0;
        
        .el-icon {
          color: #fff;
          font-size: 18px;
          cursor: pointer;
          
          &:hover {
            color: #67c23a;
          }
        }
      }
    }
  }
  
  .upload-tips {
    margin-top: 8px;
    font-size: 12px;
    color: #909399;
    display: flex;
    align-items: center;
    gap: 5px;
    
    .el-icon {
      color: #f56c6c;
    }
  }

  :deep(.el-input), :deep(.el-select), :deep(.el-tree-select), :deep(.el-input-number) {
    width: 100%;
  }
  
  :deep(.el-input__wrapper), :deep(.el-textarea__inner) {
    box-shadow: 0 0 0 1px #dcdfe6 inset;
    
    &:hover {
      box-shadow: 0 0 0 1px #c0c4cc inset;
    }
    
    &.is-focus {
      box-shadow: 0 0 0 1px #67c23a inset;
    }
  }
  
  :deep(.el-form-item__label) {
    font-weight: 500;
  }
  
  .form-note {
    display: flex;
    align-items: center;
    gap: 8px;
    color: #67c23a;
    font-size: 14px;
    padding: 8px 15px;
    background-color: #f0f9eb;
    border: 1px solid #e1f3d8;
    border-radius: 6px;
    margin-top: 28px;
    
    .note-icon {
      font-size: 16px;
    }
  }
  
  // 只读物料编码样式
  :deep(.el-input.is-disabled .el-input__wrapper) {
    background-color: #f5f7fa;
    border-color: #e4e7ed;
    cursor: not-allowed;
  }
  
  :deep(.el-input[readonly] .el-input__wrapper) {
    background-color: #f8f9fa;
    border-color: #d1d5db;
  }
}

// 导入错误详情对话框样式
.import-error-dialog {
  .result-summary {
    margin-bottom: 20px;
  }
  
  .import-stats {
    margin-bottom: 20px;
    padding: 20px;
    background-color: #f8f9fa;
    border-radius: 6px;
    
    :deep(.el-statistic__head) {
      font-size: 14px;
      color: #606266;
      margin-bottom: 8px;
    }
    
    :deep(.el-statistic__content) {
      font-size: 24px;
      font-weight: 600;
      color: #303133;
    }
  }
  
  .error-details {
    h4 {
      margin-bottom: 15px;
      color: #303133;
      font-size: 16px;
      font-weight: 600;
    }
    
    .error-table {
      :deep(.el-table__header) {
        background-color: #f5f7fa;
      }
      
      :deep(.el-table td) {
        padding: 8px 0;
      }
    }
  }
}

.full-width {
  width: 100%;
}

// 物料分类选择器样式
.category-select-wrapper {
  display: flex;
  gap: 8px;
  width: 100%;
  
  .category-select {
    flex: 1;
    
    // 自定义选项样式
    :deep(.el-select-dropdown__item) {
      height: auto;
      padding: 8px 20px;
      line-height: 1.4;
      
      .category-option {
        display: flex;
        flex-direction: column;
        
        .category-name {
          font-size: 14px;
          color: #303133;
          font-weight: 500;
        }
        
        .category-parent {
          font-size: 12px;
          color: #909399;
          margin-top: 2px;
          
          &::before {
            content: "上级: ";
          }
        }
      }
      
      &:hover {
        background-color: #f5f7fa;
      }
      
      &.selected {
        background-color: #e6f7ff;
        color: #1890ff;
        
        .category-name {
          color: #1890ff;
          font-weight: 600;
        }
      }
    }
  }
  
  .add-category-btn {
    flex-shrink: 0;
    height: 32px;
    padding: 0 12px;
    font-size: 12px;
    border-radius: 4px;
    background: linear-gradient(135deg, #67c23a, #529b2e);
    border: none;
    transition: all 0.3s;
    
    &:hover {
      transform: translateY(-2px);
      box-shadow: 0 4px 12px rgba(103, 194, 58, 0.3);
      opacity: 0.9;
    }
    
    &:active {
      transform: translateY(0);
    }
  }
}

// 新增物料分类对话框样式
:deep(.category-dialog) {
  border-radius: 8px;
  overflow: hidden;
  
  .el-dialog__header {
    padding: 15px 20px;
    margin: 0;
    background: linear-gradient(90deg, #f0f9eb, #e1f3d8);
    border-bottom: 1px solid #e1f3d8;
    
    .el-dialog__title {
      font-size: 16px;
      font-weight: 600;
      color: #67c23a;
    }
    
    .el-dialog__headerbtn {
      top: 15px;
    }
  }
  
  .el-dialog__body {
    padding: 20px;
  }
  
  .el-dialog__footer {
    padding: 10px 20px;
    border-top: 1px solid #ebeef5;
    background-color: #f5f7fa;
  }
}

.category-form {
  .form-tips {
    margin-top: 8px;
    font-size: 12px;
    color: #909399;
    display: flex;
    align-items: center;
    gap: 5px;
    
    .el-icon {
      color: #67c23a;
    }
  }
  
  :deep(.el-input), :deep(.el-textarea), :deep(.el-tree-select) {
    width: 100%;
  }
  
  :deep(.el-input__wrapper), :deep(.el-textarea__inner) {
    box-shadow: 0 0 0 1px #dcdfe6 inset;
    
    &:hover {
      box-shadow: 0 0 0 1px #c0c4cc inset;
    }
    
    &.is-focus {
      box-shadow: 0 0 0 1px #67c23a inset;
    }
  }
  
  :deep(.el-form-item__label) {
    font-weight: 500;
    color: #303133;
  }
}

// 图片预览对话框样式
:deep(.preview-dialog) {
  border-radius: 8px;
  overflow: hidden;
  
  .el-dialog__header {
    padding: 15px 20px;
    margin: 0;
    background: linear-gradient(90deg, #f0f9eb, #e1f3d8);
    border-bottom: 1px solid #e1f3d8;
    
    .el-dialog__title {
      font-size: 16px;
      font-weight: 600;
      color: #67c23a;
    }
    
    .el-dialog__headerbtn {
      top: 15px;
    }
  }
  
  .el-dialog__body {
    padding: 0;
  }
  
  .el-dialog__footer {
    padding: 10px 20px;
    border-top: 1px solid #ebeef5;
    background-color: #f5f7fa;
  }
}

.preview-container {
  width: 100%;
  height: 500px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #000;
  overflow: hidden;
  
  .preview-image {
    max-width: 100%;
    max-height: 500px;
    object-fit: contain;
  }
}

.preview-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

// 导入导出对话框样式
:deep(.import-dialog),
:deep(.export-dialog) {
  border-radius: 8px;
  overflow: hidden;
  
  .el-dialog__header {
    padding: 15px 20px;
    margin: 0;
    background: linear-gradient(90deg, #f0f9eb, #e1f3d8);
    border-bottom: 1px solid #e1f3d8;
    
    .el-dialog__title {
      font-size: 16px;
      font-weight: 600;
      color: #67c23a;
    }
  }
  
  .el-dialog__body {
    padding: 20px;
  }
  
  .el-dialog__footer {
    padding: 10px 20px;
    border-top: 1px solid #ebeef5;
    background-color: #f5f7fa;
  }
}

.field-checkboxes {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px 20px;
  max-height: 300px;
  overflow-y: auto;
  padding: 10px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  background-color: #fafafa;
  
  .field-checkbox {
    margin: 0;
    
    :deep(.el-checkbox__label) {
      color: #606266;
      font-size: 14px;
    }
    
    :deep(.el-checkbox__input.is-checked .el-checkbox__inner) {
      background-color: #67c23a;
      border-color: #67c23a;
    }
  }
}

.upload-demo {
  :deep(.el-upload-dragger) {
    border: 2px dashed #67c23a;
    border-radius: 8px;
    background-color: #f0f9eb;
    transition: all 0.3s;
    
    &:hover {
      border-color: #529b2e;
      background-color: #e1f3d8;
    }
    
    .el-icon--upload {
      color: #67c23a;
      font-size: 48px;
      margin-bottom: 10px;
    }
  }
  
  :deep(.el-upload__text) {
    color: #67c23a;
    font-size: 14px;
    
    em {
      color: #529b2e;
      font-style: normal;
      text-decoration: underline;
    }
  }
  
  :deep(.el-upload__tip) {
    color: #909399;
    font-size: 12px;
    margin-top: 8px;
  }
}

// 工艺输入框包装器样式
.process-input-wrapper {
  display: flex;
  gap: 8px;
  width: 100%;
  
  .process-input {
    flex: 1;
  }
  
  .add-process-btn {
    flex-shrink: 0;
    height: 32px;
    padding: 0 12px;
    font-size: 12px;
    border-radius: 4px;
    background: linear-gradient(135deg, #67c23a, #529b2e);
    border: none;
    transition: all 0.3s;
    
    &:hover {
      transform: translateY(-2px);
      box-shadow: 0 4px 12px rgba(103, 194, 58, 0.3);
      opacity: 0.9;
    }
    
    &:active {
      transform: translateY(0);
    }
  }
}

// 新增工艺价格对话框样式
:deep(.process-dialog) {
  border-radius: 8px;
  overflow: hidden;
  
  .el-dialog__header {
    padding: 15px 20px;
    margin: 0;
    background: linear-gradient(90deg, #f0f9eb, #e1f3d8);
    border-bottom: 1px solid #e1f3d8;
    
    .el-dialog__title {
      font-size: 16px;
      font-weight: 600;
      color: #67c23a;
    }
    
    .el-dialog__headerbtn {
      top: 15px;
    }
  }
  
  .el-dialog__body {
    padding: 20px;
    max-height: 70vh;
    overflow-y: auto;
  }
  
  .el-dialog__footer {
    padding: 10px 20px;
    border-top: 1px solid #ebeef5;
    background-color: #f5f7fa;
    
    .el-button {
      padding: 8px 20px;
      border-radius: 4px;
      transition: all 0.3s;
      
      &:hover {
        transform: translateY(-2px);
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
      }
    }
  }
}

.process-form {
  .form-card {
    margin-bottom: 15px;
    border-radius: 8px;
    transition: all 0.3s;
    overflow: hidden;
    border: 1px solid #ebeef5;
    
    &:last-child {
      margin-bottom: 0;
    }
    
    :deep(.el-card__header) {
      padding: 10px 15px;
      background: linear-gradient(90deg, #f0f9eb, #e1f3d8);
      border-bottom: 1px solid #e1f3d8;
    }
    
    .form-header {
      font-size: 16px;
      font-weight: 600;
      color: #67c23a;
      display: flex;
      align-items: center;
      gap: 8px;
      
      .el-icon {
        color: #67c23a;
      }
    }
  }
  
  :deep(.el-input), :deep(.el-select), :deep(.el-input-number) {
    width: 100%;
  }
  
  :deep(.el-input__wrapper), :deep(.el-select__wrapper) {
    box-shadow: 0 0 0 1px #dcdfe6 inset;
    
    &:hover {
      box-shadow: 0 0 0 1px #c0c4cc inset;
    }
    
    &.is-focus {
      box-shadow: 0 0 0 1px #67c23a inset;
    }
  }
  
  :deep(.el-form-item__label) {
    font-weight: 500;
    color: #303133;
  }
}

// 批量操作区域过渡动画
.batch-slide-enter-active,
.batch-slide-leave-active {
  transition: all 0.3s ease;
}

.batch-slide-enter-from {
  opacity: 0;
  transform: translateY(-10px);
}

.batch-slide-leave-to {
  opacity: 0;
  transform: translateY(-10px);
}

// 批量操作区域样式
.batch-operations {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 20px;
  margin-top: 15px;
  background: linear-gradient(135deg, #e6f7ff, #f0f9eb);
  border: 1px solid #d1ecf1;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
  
  .batch-info {
    display: flex;
    align-items: center;
    gap: 15px;
    
    .select-all-checkbox {
      :deep(.el-checkbox__label) {
        font-weight: 500;
        color: #303133;
      }
      
      :deep(.el-checkbox__input.is-checked .el-checkbox__inner) {
        background-color: #67c23a;
        border-color: #67c23a;
      }
      
      :deep(.el-checkbox__input.is-indeterminate .el-checkbox__inner) {
        background-color: #67c23a;
        border-color: #67c23a;
      }
    }
    
    .selected-count {
      font-size: 14px;
      color: #606266;
      font-weight: 500;
      padding: 4px 12px;
      background-color: #f0f9eb;
      border-radius: 4px;
      border: 1px solid #e1f3d8;
    }
    
    .el-tag {
      margin-left: 8px;
      
      .el-icon {
        margin-right: 4px;
        font-size: 12px;
      }
    }
  }
  
  .batch-buttons {
    display: flex;
    gap: 10px;
    
    .el-button {
      border-radius: 6px;
      transition: all 0.3s;
      
      &:hover {
        transform: translateY(-2px);
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
      }
      
      &:active {
        transform: translateY(0);
      }
      
      &.el-button--success {
        background: linear-gradient(135deg, #67c23a, #529b2e);
        border: none;
        
        &:hover {
          opacity: 0.9;
        }
      }
      
      &.el-button--warning {
        background: linear-gradient(135deg, #e6a23c, #cf7e2e);
        border: none;
        
        &:hover {
          opacity: 0.9;
        }
      }
    }
  }
}
</style>
